package utils

import (
	"bufio"
	"log"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"runtime"
	"strings"
)

// 判断文件夹是否存在
func PathExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

// 递归创建文件夹
func CreateDir(path string) error {
	ok, err := PathExists(path)
	if err != nil {
		return err
	}
	if ok {
		return nil
	}
	return os.MkdirAll(path, os.ModePerm)
}

// 删除文件
func RemoveFile(path string) error {
	return os.Remove(path)
}

// 删除文件夹
func RemoveDir(path string) error {
	return os.RemoveAll(path)
}

// 写文件
func WriteFile(path, str string) error {
	err := os.WriteFile(path, []byte(str), 0644)
	if err != nil {
		return err
	}
	return nil
}

// 写文件以bufio有缓冲方式
func WriteFileByBufio(path, str string) error {
	file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		log.Println(err)
		return err
	}
	defer file.Close()
	writer := bufio.NewWriter(file)
	_, err = writer.WriteString(str)
	if err != nil {
		log.Println(err)
		return err
	}
	writer.Flush()
	return nil
}

// 读文件一次性返回文件内容
func ReadFile(file string) (data string) {
	bytes, err := os.ReadFile(file)
	if err != nil {
		log.Println(err.Error())
		return ""
	}
	return string(bytes)
}

// 获取当前工作目录
func GetPWD() string {
	cmd := exec.Command("pwd")
	if out, err := cmd.CombinedOutput(); err != nil {
		return strings.ReplaceAll(string(out), "\n", "")
	} else {
		return strings.ReplaceAll(string(out), "\n", "")
	}
}

// 获取程序执行目录
func GetRunPath() (string, error) {
	path, err := filepath.Abs(filepath.Dir(os.Args[0]))
	return path, err
}

// 最终方案-全兼容
func GetCurrentAbPath() string {
	dir := GetCurrentAbPathByExecutable()
	if strings.Contains(dir, GetTmpDir()) {
		return GetCurrentAbPathByCaller()
	}
	return dir
}

// 获取系统临时目录
func GetTmpDir() string {
	dir := os.Getenv("TEMP")
	if dir == "" {
		dir = os.Getenv("TMP")
		res, _ := filepath.EvalSymlinks(dir)
		return res
	}
	return dir
}

// 获取当前执行文件绝对路径
func GetCurrentAbPathByExecutable() string {
	exePath, err := os.Executable()
	if err != nil {
		log.Fatal(err)
		res, _ := filepath.EvalSymlinks(filepath.Dir(exePath))
		return res
	}
	return exePath
}

// 获取当前执行文件绝对路径（go run）
func GetCurrentAbPathByCaller() string {
	var abPath string
	_, filename, _, ok := runtime.Caller(0)
	if ok {
		abPath = path.Dir(filename)
		return abPath
	}
	return ""
}
